<template>
  <div class="my-form">
    <div class="header">
      <slot name="header"></slot>
    </div>
    <el-form :label-width="labelWidth">
      <el-row>
        <template v-for="item in formItems" :key="item.label">
          <el-col v-bind="colLayout">
            <el-form-item
              v-if="!item.isHidden"
              :label="item.label"
              :rules="item.rules"
              :style="itemStyle"
            >
              <template
                v-if="item.type === 'input' || item.type === 'password'"
              >
                <!-- v-model="formData[`${item.field}`]" -->
                <el-input
                  :model-value="props.modelValue[`${item.field}`]"
                  @update:modelValue="handleValueChange($event, item.field)"
                  :placeholder="item.placeholder"
                  v-bind="item.otherOptions"
                  :show-password="item.type === 'password'"
                ></el-input>
              </template>
              <template v-else-if="item.type === 'select'">
                <el-select
                  :model-value="props.modelValue[`${item.field}`]"
                  @update:modelValue="handleValueChange($event, item.field)"
                  :placeholder="item.placeholder"
                  style="width: 100%"
                  v-bind="item.otherOptions"
                >
                  <el-option
                    v-for="option in item.options"
                    :key="option.value"
                    :value="option.value"
                    >{{ option.title }}</el-option
                  >
                </el-select>
              </template>
              <template v-else-if="item.type === 'datepicker'">
                <el-date-picker
                  v-bind="item.otherOptions"
                  :model-value="props.modelValue[`${item.field}`]"
                  @update:modelValue="handleValueChange($event, item.field)"
                  style="width: 100%"
                >
                </el-date-picker>
              </template>
            </el-form-item>
          </el-col>
        </template>
      </el-row>
    </el-form>
    <div class="footer">
      <slot name="footer"></slot>
    </div>
  </div>
</template>

<script setup lang="ts">
import { PropType, ref, watch } from 'vue'
import type { IFormItem } from '../types'

const props = defineProps({
  formItems: {
    type: Array as PropType<IFormItem[]>,
    // type: IFormItem[],
    //基本类型直接写 数组对象箭头函数
    default: () => []
  },
  labelWidth: {
    type: String,
    default: '100px'
  },
  itemStyle: {
    type: Object,
    default: () => ({ padding: '10px 40px' })
  },
  colLayout: {
    type: Object,
    default: () => ({
      xl: 6,
      lg: 8,
      md: 12,
      sm: 24,
      xs: 24
    })
  },
  //v-model:modelValue="formData" modelValue is default Value
  modelValue: {
    type: Object,
    required: true
  }
})
const emit = defineEmits([`update:modelValue`])
//使用reactive传入props 时候代表该方法在set时候没用调用 仍然直接更改传入的reactive 应使用watch 一个新对象改变
// const formData = computed({
//   get: () => props.modelValue,
//   set: (newValue) => {
//     console.log(1111111)
//     emit(`update:modelValue`, newValue)
//   }
// })

//无法刷新的原因：ref+浅拷贝字符串类型=>值的直接复制 新的对象 无法侦测到原先数据的变化
// const formData = ref({ ...props.modelValue })
// const formData = computed(() => ({ ...props.modelValue }))

//computed穿入一个getter函数=>不可变ref 或者一个对象含有getset方法 get:()set:() 可变ref
//watch 直接监听一个ref 或者监听一个getter(回调)
// watch(
//   () => props.modelValue,
//   (newValue) => {
//     formData.value = { ...newValue }
//   }
// )
const handleValueChange = (value: any, field: string) => {
  emit('update:modelValue', { ...props.modelValue, [field]: value })
}
// watch(
//   formData,
//   (newValue) => {
//     console.log(111)

//     emit(`update:modelValue`, newValue)
//   },
//   { deep: true }
// )
</script>

<style scoped lang="less">
.my-form {
  padding-top: 22px;
}
</style>
